/** 容器让内容横向展示并且自动换行的flex布局
 * 使用方法：v-flex="300" 或 v-flex="'30rem'"
 * value: 一个元素最小的宽度，只有数字则单位默认为px，等同于子元素的flex-basis
 * 
 * modifiers: 
 * 1. grow: 子元素是否允许变大(flex-grow)，默认1，设置后将变为0，即大小固定不变
 */

function updated(el, binding) {
  // 设置class和style
  el.classList.add("fcw");
  el.style.setProperty("--grow", binding.modifiers.grow ? '0' : '1');
  el.style.setProperty("--basis", isNaN(binding.value) ? binding.value : binding.value + 'px');
  // 计算一行的元素个数，给最后一行增加空元素占位
  let y;      // 通过y坐标不一样了来判断一行的元素个数
  let c = 0;  // 一行的子元素个数
  for (; c < el.children.length; c++) {
    const item = el.children[c];
    if (c == 0)
      y = item.getBoundingClientRect().y;
    else if (y != item.getBoundingClientRect().y || item.id == 'nil')
      break;
  }
  let n = 0;  // 指令已经添加的空白元素的数量
  for (let i = el.children.length - 1; i >= 0; i--) {
    if (el.children[i].id == 'nil')
      n++;
    else
      break;
  }
  let need = c - ((el.children.length - n) % c);
  if (need == c)
    need = 0;
  if (need != n) {
    if (need > n) {
      // 加空元素
      for (let i = n; i < need; i++) {
        const nil = el.children[0].cloneNode();
        nil.id = 'nil';
        el.appendChild(nil);
      }
    } else {
      // 减少空元素
      for (let i = el.children.length - 1; i >= 0 && n > need; i--, n--)
        el.children[i].remove();
    }
  }
  // 给每行的最后一个元素增加last标记以方便写样式(使用 gap 解决了)
  // for (let i = 0; i < el.children.length; i++)
  //   if ((i + 1) % c == 0)
  //     el.children[i].setAttribute('last', '');
  //   else
  //     el.children[i].removeAttribute('last');
}

export default {
  created(el, binding) {
    const watcher = new ResizeObserver((entries) => {
      requestAnimationFrame(() => {
        if (!el.__flex)
          return;
        if (el.__flex.width != (entries[0].contentRect.width | 0)) {
          el.__flex.width = (entries[0].contentRect.width | 0);
          updated(el, binding);
        }
      })
    })
    watcher.observe(el);
    el.__flex = {
      watcher,
      width: 0,
    };
  },
  // mounted: updated,
  updated,
  unmounted(el) {
    el.__flex.watcher.unobserve(el);
    el.__flex.watcher.disconnect();
    delete el.__flex;
  }
} 